package org.ecype.diego;

import org.ecype.util.Nulls;

import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import androidx.persistence.PersistenceException;

public class ManyToOneProcessor extends AbstractUriProcessor {

	private final Reference reference;
	private final String[] linkToParentProjection;

	public ManyToOneProcessor(Reference reference) {
		this.reference = reference;
		linkToParentProjection = new String[] { reference.getLinkToParent() };
	}

	@Override
	public String getType(Uri uri) {
		Uri parent = queryParentId(uri);
		return provider.getType(parent);
	}

	@Override
	public Cursor query(Uri uri, Uri notifyUri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		Nulls.checkAreAreNull(selection, selectionArgs, sortOrder);
		Uri parent = queryParentId(uri);
		return provider.query(parent, notifyUri, projection, null, null, null);
	}

	@Override
	public Uri insert(Uri uri, Uri notifyUri, ContentValues values) {
		Uri parent = provider.insert(reference.getParent().getUri(), values);
		long linkToParent = Uris.parseId(parent);
		ContentValues patch = new ContentValues();
		patch.put(reference.getLinkToParent(), linkToParent);
		provider.update(extractChildUri(uri), notifyUri, patch, null, null);
		return uri;
	}

	@Override
	public int update(Uri uri, Uri notifyUri, ContentValues values, String selection, String[] selectionArgs) {
		Nulls.checkAreAreNull(selection, selectionArgs);
		Uri parent = queryParentId(uri);
		return provider.update(parent, notifyUri, values, null, null);
	}

	@Override
	public int delete(Uri uri, Uri notifyUri, String selection, String[] selectionArgs) {
		Nulls.checkAreAreNull(selection, selectionArgs);
		if (reference.isCascadeRemove()) {
			throw new PersistenceException("can't remove parent if cascade remove");
		}
		Uri parent = queryParentId(uri);
		return provider.delete(parent, notifyUri, null, null);
	}

	private Uri queryParentId(Uri uri) {
		Cursor child = provider.query(extractChildUri(uri), linkToParentProjection, null, null, null);
		//aassert(child.moveToFirst());
		if (child.moveToFirst()) {
			long parentId = child.getLong(child.getColumnIndex(reference.getLinkToParent()));
			child.close();
			return Uris.withAppendedId(reference.getParent().getUri(), parentId);
		} else {
			child.close();
			return null;
		}
	}

	private static Uri extractChildUri(Uri uri) {
		return Uris.withoutLastSegment(uri);
	}
}
